package com.robaone.gwt.hierarcialdb.server.business;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Vector;

import org.json.JSONArray;
import org.json.JSONObject;

import com.robaone.dbase.hierarchial.ConfigManager;
import com.robaone.dbase.hierarchial.HDBSessionData;
import com.robaone.gwt.hierarcialdb.client.data.DataConstants;
import com.robaone.gwt.hierarcialdb.server.HierarcialDBServiceImpl;
import com.robaone.gwt.hierarcialdb.server.templates.HDBAdminManagerInterface;

public class AdminManager implements HDBAdminManagerInterface {

	private HierarcialDBServiceImpl parent;

	public AdminManager(HierarcialDBServiceImpl hierarcialDBServiceImpl) {
		this.parent = hierarcialDBServiceImpl;
	}

	@Override
	public String[] getMenuItems() throws Exception {
		JSONObject jo = new JSONObject();
		String[] items = {"Home","Admin"};
		jo.put("items", items);
		HDBSessionData session = new HDBSessionData(System.getProperty("db_username"));
		ConfigManager menu = new ConfigManager("/sys/menu",jo,"Menu Items","Visible Menu Items",session);
		jo = menu.getJSON();
		JSONArray ja = jo.getJSONArray("items");
		String[] retval = new String[ja.length()];
		for(int i = 0; i < retval.length;i++){
			retval[i] = ja.getString(i);
		}
		ConfigManager binary_test = new ConfigManager("/test/binary data",jo.toString().getBytes(),"Test Data","This is an empty binary file","text/plain",session);
		return retval;
	}

	@Override
	public Vector<HashMap<String, String>> getFolderContentsbyPath(
			String current_path) throws Exception {
		if(current_path.startsWith("ROOT")){
			current_path = current_path.substring(4);
		}
		Vector<HashMap<String,String>> retval = new Vector<HashMap<String,String>>();
		HashMap<String,String> path = new HashMap<String,String>();
		path.put("path", current_path);
		retval.add(path);
		ConfigManager[] entries = ConfigManager.findFolderContentbyPath(current_path);
		if(entries != null){
			for(int i = 0; i < entries.length;i++){
				HashMap<String,String> folder = new HashMap<String,String>();
				folder.put("filename", entries[i].getName());
				folder.put("type", ""+entries[i].getType());
				folder.put("id", ""+entries[i].getId());
				retval.add(folder);
			}
		}
		return retval;
	}

	@Override
	public Vector<HashMap<String, String>> getFolderContentsbyId(String id)
			throws Exception {
		Vector<HashMap<String,String>> retval = new Vector<HashMap<String,String>>();
		HashMap<String,String> path = new HashMap<String,String>();
		path.put("path", parent.getAbsolutePath(new BigDecimal(id)));
		retval.add(path);
		ConfigManager[] entries = ConfigManager.findFolderContentbyId(new BigDecimal(id));
		if(entries != null){
			for(int i = 0; i < entries.length;i++){
				HashMap<String,String> folder = new HashMap<String,String>();
				folder.put("filename", entries[i].getName());
				folder.put("type", ""+entries[i].getType());
				folder.put("id", ""+entries[i].getId());
				retval.add(folder);
			}
		}
		return retval;
	}

	@Override
	public String getAbsolutePath(BigDecimal id) throws Exception {
		ConfigManager cfg = new ConfigManager(id);
		String path = cfg.getAbsolutePath();
		return path;
	}

	@Override
	public Vector<HashMap<String, String>> getFileContentsbyId(String id)
			throws Exception {
		Vector<HashMap<String,String>> retval = new Vector<HashMap<String,String>>();
		//HashMap<String,String> path = new HashMap<String,String>();
		//path.put("path", this.getAbsolutePath(new BigDecimal(id)));
		//retval.add(path);
		ConfigManager entry = new ConfigManager(new BigDecimal(id));
		if(entry != null){
			HashMap<String,String> folder = new HashMap<String,String>();
			folder.put("name", entry.getName());
			folder.put("type", ""+entry.getType());
			folder.put("id", ""+entry.getId());
			folder.put("description", entry.getDescription());
			folder.put("title", entry.getTitle());
			folder.put("created_by", entry.getCreatedBy());
			folder.put("modified_by", entry.getModifiedBy());
			folder.put("created_date", entry.getCreatedDate() == null ? "" : entry.getCreatedDate().toString());
			folder.put("modified_date", entry.getModifiedDate() == null ? "" : entry.getModifiedDate().toString());
			folder.put("path", entry.getAbsolutePath());
			folder.put("parentid", entry.getFolderID()+"");
			switch(entry.getType()){
			case DataConstants.BINARY:
				folder.put("content_type", entry.getContentType());
				break;
			case DataConstants.BOOLEAN:
				folder.put("value", entry.getBoolean() == null ? "null" : entry.getBoolean().booleanValue() ? "true" : "false");
				break;
			case DataConstants.DATETIME:
				SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
				folder.put("value", entry.getDateTime() == null ? "" : df.format(entry.getDateTime()));
				break;
			case DataConstants.DOUBLE:
				folder.put("value", entry.getDouble()+"");
				break;
			case DataConstants.FOLDER:
				break;
			case DataConstants.INT:
				folder.put("value", entry.getInt()+"");
				break;
			case DataConstants.JSON:
				JSONObject jo = entry.getJSON();
				if(jo == null){
					folder.put("value", "");
				}else{
					String str = jo.toString(2);
					folder.put("value", str);
				}
				break;
			case DataConstants.STRING:
				folder.put("value", entry.getString() == null ? "" : entry.getString());
				break;
			case DataConstants.TEXT:
				folder.put("value", entry.getString() == null ? "" : entry.getString());
				break;
			}
			retval.add(folder);
		}
		return retval;

	}

	@Override
	public HashMap<String, String> setFileContents(String text, String id)
			throws Exception {
		ConfigManager cfg = new ConfigManager(new BigDecimal(id));
		int ftype = cfg.getType();
		HashMap<String,String> retval = new HashMap<String,String>();
		String host = parent.getRemoteHost();
		HDBSessionData session = new HDBSessionData("root",host);
		if(ftype == DataConstants.STRING){
			cfg.setValue(text, session);
			retval.put("status", DataConstants.OK_STATUS);
		}else if(ftype == DataConstants.INT){
			try{
				if(text != null){
					int i = Integer.parseInt(text);
					cfg.setValue(i, session);
				}else{
					cfg.setValueAsNull(session);
				}
				retval.put("status", DataConstants.OK_STATUS);
			}catch(Exception e){
				retval.put("status", DataConstants.FIELD_ERROR);
				retval.put("error", "Value is not an integer");
			}
		}else if(ftype == DataConstants.DOUBLE){
			try{
				if(text != null){
					double d = Double.parseDouble(text);
					cfg.setValue(d, session);
				}else{
					cfg.setValueAsNull(session);
				}
				retval.put("status", DataConstants.OK_STATUS);
			}catch(Exception e){
				retval.put("status", DataConstants.FIELD_ERROR);
				retval.put("error", "Value is not a double");
			}
		}else if(ftype == DataConstants.BOOLEAN){
			try{
				if(text != null){
					if("true".equalsIgnoreCase(text.trim())){
						cfg.setValue(true, session);
					}else if("false".equalsIgnoreCase(text.trim())){
						cfg.setValue(false, session);
					}else if("1".equals(text.trim())){
						cfg.setValue(true, session);
					}else if("0".equals(text.trim())){
						cfg.setValue(false, session);
					}else if("y".equalsIgnoreCase(text.trim()) || "yes".equalsIgnoreCase(text.trim())){
						cfg.setValue(true, session);
					}else if("n".equalsIgnoreCase(text.trim()) || "no".equalsIgnoreCase(text.trim())){
						cfg.setValue(false, session);
					}else{
						retval.put("status", DataConstants.FIELD_ERROR);
						retval.put("error", "Value is not a boolean value.  Valid entries are \"true\" and \"false\"");
					}
				}else{
					cfg.setValueAsNull(session);
				}
				retval.put("status", DataConstants.OK_STATUS);
			}catch(Exception e){
				retval.put("status", DataConstants.ERROR);
				retval.put("error", e.getMessage());
			}
		}else if(ftype == DataConstants.DATETIME){
			try{
				if(text != null){
					SimpleDateFormat df = new SimpleDateFormat("mm/dd/yyyy hh:mm a");
					java.util.Date d = df.parse(text.trim());
					cfg.setValue(new java.sql.Timestamp(d.getTime()), session);
				}else{
					cfg.setValueAsNull(session);
				}
				retval.put("status", DataConstants.OK_STATUS);
			}catch(Exception e){
				retval.put("status", DataConstants.FIELD_ERROR);
				retval.put("error", "Value is not a valid date.  A valid date is in the format of MM/dd/yyyy hh:mm a");
			}
		}else if(ftype == DataConstants.TEXT){
			try{
				if(text != null){
					cfg.setValue(text, session);
				}else{
					cfg.setValueAsNull(session);
				}
				retval.put("status", DataConstants.OK_STATUS);
			}catch(Exception e){
				retval.put("status", DataConstants.ERROR);
				retval.put("error", e.getMessage());
			}
		}else if(ftype == DataConstants.BINARY){
			retval.put("status", DataConstants.ERROR);
			retval.put("error", "This feature is not yet supported");
		}else if(ftype == DataConstants.JSON){
			try{
				JSONObject json = new JSONObject(text);
				cfg.setValue(json, session);
				retval.put("status", DataConstants.OK_STATUS);
			}catch(Exception e){
				retval.put("status", DataConstants.FIELD_ERROR);
				retval.put("error","Value is not a valid json object.  Please check your syntax and try again.");
			}
		}
		return retval;
	}

}
